home *** CD-ROM | disk | FTP | other *** search
- ===========================================================================
- Freeciv Style Guide
- ===========================================================================
-
- If you want to hack Freeciv, and want your patches to be accepted, it
- helps to follow some simple style rules. Yes, some of these are a bit
- nit-picky, but wars are fought over the silliest things...
-
- - Freeciv is programmed in plain C (except the BEOS client). This
- means that C++ features like:
- - C++-style comments (i.e., // comments) and
- - declaration variables in the middle of the function body
- are forbidden.
-
- - Use K&R indentation style with indentation 2 (if in doubt, use
- "indent -kr -i2 -l77"). However, do not re-indent areas of code you
- are not modifying or creating. Here are the most important properties:
- - lines are at most 77 chars long
- - spaces are inserted before and after operators (instead of
- "int a,b,c;" use "int i, j, k;" and instead of "if(foo<=bar) c=a+b;"
- use "if (foo <= bar) c = a + b;" -- note the space between "if"
- and the bracket)
- - function braces begin and end in the first column.
- int foo()
- {
- return 0;
- }
- instead of
- int foo() {
- return 0;
- }
- - the tab width is 8
- - the indentation is 2 columns per level
-
- - An empty line should be placed between two separate blocks of code.
-
- - Place operators at the beginning of a line, not at the end. It should be
- if ((a
- && b)
- || c) {
- instead of
- if ((a &&
- b) ||
- c) {
-
- ================================
- Comments
- ================================
-
- - Every function should have a comment header. The comment should look
- like the example below, indented by two spaces. It should be above the
- function's implementation, not the prototype:
-
- /*************************************************************************
- the description of the function should be here
- any information is helpful, such as who calls this function, etc.
- do _not_ introduce a new function without some sort of comment.
- *************************************************************************/
- int the_function_starts_here(int value)
- {
- ...
- }
-
- - One line comments. Comments should be indented correctly and
- placed above the code being commented upon:
-
- int x;
-
- /* I am a single line comment */
- x = 3;
-
- - Multiline comments. Asterisks should be placed in front of the
- comment line like so:
-
- /* I am a multiline
- * comment, blah
- * blah blah */
-
- - Comments in declarations. If you need to comment a declared variable,
- it should be as such:
-
- struct foo {
- int bar; /* bar is used for ....
- * in ..... way */
- int blah; /* blah is used for .... */
- };
-
- - Comments in conditionals. If you need a comment to show program flow,
- it should be below the if or else:
-
- if (is_barbarian(pplayer)) {
- x++;
- } else {
- /* If not barbarian, ... */
- x--;
- }
-
- - Comments to translators are stored before the N_(), _() or Q_() marked
- string, and are preceded by "TRANS:". These comments are copied to the
- translators file. Use them whenever you think the translators may need
- some more information:
-
- /* TRANS: Don't translate "commandname". */
- printf(_("commandname <arg> [-o <optarg>]"));
-
- ================================
- Declaring variables
- ================================
-
- - Variables can be initialized as soon as they're declared:
-
- int foo(struct unit *punit)
- {
- int x = punit->x;
- int foo = x;
- char *blah;
-
- ...
- }
-
- - After variables are declared, there should be an empty line before the
- rest of the function body.
-
- - Merging declarations. Variables do not have to be declared one per line;
- however, they should only be grouped by similar function.
-
- int foo(struct city *pcity)
- {
- int i, j, k;
- int total, cost;
- int build = pcity->shield_stock;
- }
-
- ================================
- Bracing
- ================================
-
- - Extra braces on iterates. Note that the *_iterate_end; should be placed
- on the same line as the end brace:
-
- unit_list_iterate(pcity->units_supported, punit) {
- kill(punit);
- } unit_list_iterate_end;
-
- - In switch statements, braces should only be placed where needed, i.e. to
- protect local variables.
-
- - Braces shall be used after conditionals:
-
- if (x == 3) {
- return;
- }
-
- and
-
- if (x == 3) {
- return 1;
- } else {
- return 0;
- }
-
- not
-
- if (x == 3)
- return 1; /* BAD! */
-
- ================================
- Other stuff
- ================================
-
- - If an empty block is needed you should put an explanatory comment in
- an empty block (i.e. {}):
-
- while (*i++) {
- /* nothing */
- }
-
- - Use the postfix operator instead of the prefix operator when either will
- work. That is, write "a++" instead of "++a".
-
- - Order include files consistently: All includes are grouped
- together. These groups are divided by an empty line. The order of
- these groups are as follow:
-
- 1) config.h (see below)
- 2) system include files which are OS-independent (part of
- C-standard or POSIX)
- 3) system include files which are OS-dependent or conditional
- includes
- 4) include files from common/ and common/aicore
- 5) include files from client/, client/include and client/agents
- 6) include files from client/gui-*
- 7) include files from server/
- 8) include files from ai/
-
- Each group is sorted in alphabetic order. This helps to avoid adding
- unnecessary or duplicated include files.
-
- It is very important that '#include <config.h>' be included at the top of
- every .c file (it need not be included from .h files). Some definitions in
- config.h will affect how the code is compiled, without which you can end
- up with bad and untraceable memory bugs.
-
- - If you use a system specific feature, don't add #ifdef __CRAY__ or
- something like that. Rather write a check for that feature for
- both configure.in and configure.ac, and use a meaningful macro name
- in the source.
-
- - Always prototype global functions in the appropriate header file.
- Local functions should always be declared as static. To catch these
- and some other problems please use the following warning options
- "-Wall -Wpointer-arith -Wcast-align -Wmissing-prototypes
- -Wmissing-declarations -Wstrict-prototypes -Wnested-externs" if you
- use gcc.
-
- - Header files should be compatible with C++ but code (.c) files need not
- be. This means some C++ keywords (like "this" or "class") may not be
- used in header files. It also means casts on void pointers (which should
- be avoided in C files) must be used in headers.
-
- - If you send patches, use "diff -u" (or "diff -r -u"). "svn diff" works
- correctly without extra parameters.
- For further information, see
- <http://www.freeciv.org/index.php/How_to_Contribute>.
- Also, name patch files descriptively (e.g. "fix-foo-bug-0.diff" is good,
- but "freeciv.diff" is not).
-
- - When doing a "diff" for a patch, be sure to exclude unnecessary files
- by using the "-X" argument to "diff". E.g.:
-
- % diff -ruN -Xdiff_ignore freeciv_svn freeciv >/tmp/fix-foo-bug-0.diff
-
- A suggested "diff_ignore" file is included in the Freeciv distribution.
-
- ===========================================================================
-